/****************************************************
	文件：ContextManager.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2021/2/7 21:10:6
	功能：上下文管理器
*****************************************************/

using System.Collections.Generic;
using UnityEngine;
using HTFW.Logger;
using HTFW.Utility.Global;

namespace HTFW.Core
{
    public class ContextManager : Singleton<ContextManager>, IManager, ITimerUpdate
    {
        MonoBehaviour mMono;

        Dictionary<ContextType, Dictionary<ContextScope, IContext>> mAllContextDict; //所有的上下文缓存
        List<TimerContext> mTimerContextLst;

        public void Init(params object[] args)
        {
            mMono = (MonoBehaviour) args[0];

            mAllContextDict = new Dictionary<ContextType, Dictionary<ContextScope, IContext>>();
            mTimerContextLst = new List<TimerContext>();
        }

        public void Dispose()
        {
            foreach (var item in mAllContextDict)
            {
                if (item.Key == ContextType.Unit)
                {
                    foreach (var context in item.Value)
                        context.Value.Dispose();
                }
            }

            mAllContextDict = null;
            mTimerContextLst = null;
        }

        /// <summary>
        /// 创建上下文
        /// </summary>
        /// <param name="type"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public T CreateContext<T>(ContextType type, ContextScope scope) where T : IContext
        {
            IContext context = null; //构造
            switch (type)
            {
                case ContextType.Unit:
                    context = new UnitContext();
                    break;
                case ContextType.Res:
                    context = new ResContext();
                    break;
                case ContextType.Timer:
                    context = new TimerContext();
                    break;
                case ContextType.Coroutine:
                    context = new CoroutineContext();
                    break;
                case ContextType.Event:
                    context = new EventContext();
                    break;
                default:
                    HLog.Error($"CreateContext error! 尚未处理的 ContextType : {type}");
                    break;
            }

            if (context != null)
            {
                context.ContextType = type; //属性赋值
                context.ContextScope = scope;

                if (mAllContextDict.TryGetValue(type, out var dict)) //缓存
                {
                    if (dict == null)
                        dict = new Dictionary<ContextScope, IContext>();

                    if (dict.ContainsKey(scope))
                    {
                        HLog.Error(
                            $"CreateContext error! 同一作用域下只可创建一个同种上下文，ContextScope : {scope}，ContextType ：{type}");
                        return default;
                    }
                    else
                        dict.Add(scope, context);
                }
                else
                {
                    var tempDict = new Dictionary<ContextScope, IContext>();
                    tempDict.Add(scope, context);
                    mAllContextDict.Add(type, tempDict);
                }

                if (type == ContextType.Timer)
                    mTimerContextLst.Add((TimerContext) context);
            }

            return (T)context;
        }

        /// <summary>
        /// 删除指定上下文
        /// </summary>
        /// <param name="type"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public bool DeleteContext(ContextType type, ContextScope scope)
        {
            if (mAllContextDict.TryGetValue(type, out var dict))
            {
                if (dict.TryGetValue(scope, out var context))
                {
                    context.Dispose();
                    dict.Remove(scope);
                    return true;
                }
                else
                {
                    HLog.Error($"DeleteContext error! 缓存中不存在 ContextScope : {scope}");
                    return false;
                }
            }
            else
            {
                HLog.Error($"DeleteContext error! 缓存中不存在 ContextType : {type}");
                return false;
            }
        }

        /// <summary>
        /// 删除指定上下文
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool DeleteContext(IContext context)
        {
            if (context.ContextType == ContextType.Timer)
                mTimerContextLst.Remove((TimerContext) context);

            return DeleteContext(context.ContextType, context.ContextScope);
        }

        /// <summary>
        /// 尝试获取指定上下文
        /// </summary>
        /// <param name="type"></param>
        /// <param name="scope"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool TryGet(ContextType type, ContextScope scope, out IContext context)
        {
            if (mAllContextDict.TryGetValue(type, out var dict))
            {
                if (dict.TryGetValue(scope, out context))
                    return true;
                else
                    return false;
            }
            else
            {
                context = null;
                return false;
            }
        }

        public void OnTimerUpdate()
        {
            for (int i = mTimerContextLst.Count - 1; i >= 0; i--)
                mTimerContextLst[i].OnTimerUpdate();
        }
    }
}